package com.ksyun.cloudhostalarmprocessing.service.Impl;

import com.ksyun.cloudhostalarmprocessing.entity.Alerts;
import com.ksyun.cloudhostalarmprocessing.entity.Metrics;
import com.ksyun.cloudhostalarmprocessing.entity.Rules;
import com.ksyun.cloudhostalarmprocessing.mapper.AlertsMapper;
import com.ksyun.cloudhostalarmprocessing.mapper.RulesMapper;
import com.ksyun.cloudhostalarmprocessing.service.RealTimeComputingService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  实时服务实现类
 * </p>
 *
 * @author 李厚航
 * @since 2024-05-06
 */
@Service
public class RealTimeComputingServiceImpl implements RealTimeComputingService {

    @Resource
    private RulesMapper rulesMapper;

    @Resource
    private AlertsMapper alertsMapper;


//    public void calculateBatch(List<Metrics> metrics){
//        //查询rules数据库，返回所有规则信息
//        List<Rules> rulesList = rulesMapper.selectBatch(new Rules());
//        //通过规则遍历所有metrics对象，查看哪些需要告警
//        List<Alerts> alerts = metrics.stream().map(m -> rulesList.stream().map(rules -> {
//            Alerts a = null;
//            if(rules.getMetricName().equals(m.getMetricName())){
//                //判断是否触发告警
//                Boolean res = false;
//                switch (m.getMetricName()){
//                    case "up" -> res = downTime(m,rules);
//                    case "node_netstat_Tcp_CurrEstab" -> res = theNumberOfHostConnectionsIsTooHigh(m,rules);
//                    case "node_filesystem_free_bytes" -> res = insufficientDiskSpaceRemaining(m,rules);
//                    case "node_load5" -> res = cpuLoadTooHighWithinFiveMinutes(m,rules);
//                    case "node_memory_MemFree_bytes" -> res = lowSpaceAndMemory(m,rules);
//                }
//                if(!res){
//                    return null;
//                }
//                //生成告警对象
//                a = new Alerts( m.getMetricId(), rules.getRuleName());
////                //添加一条告警
////                alertsService.add(a);
//            }
//            //返回告警
//            return a;
//        }).collect(Collectors.toList())).flatMap(List::stream).filter(Objects::nonNull).collect(Collectors.toList());
//        //处理告警
//        if(!alerts.isEmpty()){
//            action(alerts);
//        }
//    }


//    @Override
//    public void calculate(List<Metrics> metrics) {
//
//    }

    @Override
    @Transactional
    public void calculate(List<Metrics> metrics) {
        //查询rules数据库，返回所有规则信息
        List<Rules> rulesList = rulesMapper.selectBatch(new Rules());
        //通过规则遍历所有metrics对象，查看哪些需要告警
        List<Alerts> alerts = metrics.stream().map(m -> rulesList.stream().map(rules -> {
            Alerts a = null;
            if(rules.getMetricName().equals(m.getMetricName())){
                //判断是否触发告警
                Boolean res = false;
                switch (m.getMetricName()){
//                    case "up" -> res = downTime(m,rules);
                    case "up":
                        res = downTime(m,rules);
                        break;
                    case "node_netstat_Tcp_CurrEstab":
                        res = theNumberOfHostConnectionsIsTooHigh(m,rules);
                        break;
                    case "node_filesystem_free_bytes":
                        res = insufficientDiskSpaceRemaining(m,rules);
                        break;
                    case "node_load5":
                        res = cpuLoadTooHighWithinFiveMinutes(m,rules);
                        break;
                    case "node_memory_MemFree_bytes":
                        res = lowSpaceAndMemory(m,rules);
                        break;
//                    case "node_netstat_Tcp_CurrEstab" -> res = theNumberOfHostConnectionsIsTooHigh(m,rules);
//                    case "node_filesystem_free_bytes" -> res = insufficientDiskSpaceRemaining(m,rules);
//                    case "node_load5" -> res = cpuLoadTooHighWithinFiveMinutes(m,rules);
//                    case "node_memory_MemFree_bytes" -> res = lowSpaceAndMemory(m,rules);
                }
                if(!res){
                    return null;
                }
                //生成告警对象
                a = new Alerts( m.getMetricId(), rules.getRuleName());
//                //添加一条告警
//                alertsService.add(a);
            }
            //返回告警
            return a;
        }).collect(Collectors.toList())).flatMap(List::stream).filter(Objects::nonNull).collect(Collectors.toList());
        //处理告警
        if(!alerts.isEmpty()){
            action(alerts);
        }
    }



    @Override
    public void action(List<Alerts> alerts) {
        //将告警数据入库
        alertsMapper.createBatch(alerts);
    }

    @Override
    public Boolean downTime(Metrics metrics, Rules rules) {
        return metrics.getValue().equals(rules.getValue());
    }

    @Override
    public Boolean theNumberOfHostConnectionsIsTooHigh(Metrics metrics, Rules rules) {
        return metrics.getValue() > rules.getValue();
    }

    @Override
    public Boolean insufficientDiskSpaceRemaining(Metrics metrics, Rules rules) {
        return metrics.getValue() < rules.getValue();
    }

    @Override
    public Boolean cpuLoadTooHighWithinFiveMinutes(Metrics metrics, Rules rules) {
        return metrics.getValue() >= rules.getValue();
    }

    @Override
    public Boolean lowSpaceAndMemory(Metrics metrics, Rules rules) {
        return metrics.getValue() <= rules.getValue();
    }

}
